import Data.List (elemIndex, (\\))
import Data.Maybe (fromJust)
import Data.Set (Set)
import qualified Data.Set as Set
import Grid

type Maze = Grid Char

start :: Maze -> Coord
start m@(Grid r c _) = (0, c')
    where
        c' = fromJust . elemIndex '.' $ row m 0

finish :: Make -> Coord
finish m@(Grid r c _) = (r - 1, c')
    where
        c' = fromJust . elemIndex '.' $ row m (r - 1)

neighbours :: Maze -> Coord -> [Coord]
neighbours m (r, c) = 
    case (cell m (r, c)) of
        '>' -> [(r, c + 1)],
        '<' -> [(r, c - 1)],
        '^' -> [(r - 1, c)],
        'v' -> [(r + 1, c)],
        '.' -> map fst . filter ((/='#') . snd) $ vonNeum m (r, c)

dfs :: Maze -> Coord -> [Int]
dfs m c = 
    go 0 Set.empty [c]
    where
        go ctr visited queue
            | queue == []   = []
            | q == finish m = [ctr]                        ++ go ctr visited qs
            | otherwise     = go (ctr + 1) visited' neighs ++ go ctr visited qs
                where
                    (q:qs)   = queue
                    neighs   = filter (`Set.notMember` visited) (neighbours m q)
                    visited' = (Set.insert q visited)

main = do
    input    <- readFile "input.txt"
    let maze =  Grid.fromList . lines $ input
    print $ maximum $ dfs maze (start maze)
